package com.jingdun.sport.activity

import com.jingdun.sport.authority.SecurityChecker
import com.jingdun.sport.bean.model.ApiResult
import com.jingdun.sport.common.constants.RedisConstants
import com.jingdun.sport.common.util.RedisUtil
import com.jingdun.sport.data.environment.DataEnvironment
import com.jingdun.sport.sporttype.SportConfig
import com.losttemple.sql.language.operator.*
import com.losttemple.sql.language.reflection.useAll
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.text.SimpleDateFormat

class Record {
    var activity: Int? = null
    var measure: Int = 0
    var start: String? = null
    var end: String? = null
    var video: String? = null
    var sportTypeId: Int? = 0
    var type: Int? = 0
}

@RestController
@RequestMapping("/sport/records/")
class RecordController {
    @Autowired
    private lateinit var sql: DataEnvironment

    @Autowired
    private lateinit var securityChecker: SecurityChecker

    @PostMapping("/addRecord")
    fun addRecord(@RequestBody record: Record): ResponseEntity<Any> {
        val apiResult: ApiResult<*> = ApiResult<Any?>()
        val user = securityChecker.user
        val simpleDateFormat: SimpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sql.run {
            db { SportRecords(it) }
                    .insert {
                        it.user(user.userId)
                        it.activity(record.activity)
                        it.measure(record.measure)
                        it.start(simpleDateFormat.parse(record.start))
                        it.end(simpleDateFormat.parse(record.end))
                        it.video(record.video)
                        it.status("1")
                        it.sportTypeId(record.sportTypeId)
                        it.type(record.type)
                    }()!!
        }
        var stpc = RedisUtil.get<Long>(RedisConstants.SportTypePersonCount + record.sportTypeId)
        if(stpc==null){
            stpc = 0
        }
        RedisUtil.set(RedisConstants.SportTypePersonCount + record.sportTypeId, stpc +1)
        return ResponseEntity.ok(apiResult)
    }

    @GetMapping("/{recordId}")
    fun recordDetail(@PathVariable("recordId") recordId: Int): ResponseEntity<Any> {
        val apiResult: ApiResult<*> = ApiResult<Any?>()
        val user = securityChecker.user
        val record = sql.run {
            from { SportRecords(it) }
                    .where { id eq recordId }
                    .useAll()
                    .select {
                        object {
                            val user = it.user()
                            val activity = it.activity()
                            val measure = it.measure()
                            val start = it.start()
                            val end = it.end()
                            val video = it.video()
                        }
                    }.firstOrNull()
        } ?: return ResponseEntity.ok(apiResult)
        if (record.user != user.userId) {
            apiResult.code = HttpStatus.UNAUTHORIZED.value()
            apiResult.msg = HttpStatus.UNAUTHORIZED.reasonPhrase
            return ResponseEntity.ok(apiResult)
        }
        apiResult.data = record
        return ResponseEntity.ok(apiResult)
    }

    @GetMapping("/join")
    fun userJoinedSport(): ResponseEntity<Any> {
        val apiResult: ApiResult<*> = ApiResult<Any?>()
        val user = securityChecker.user
        val record = sql.run {
            ((from { SportRecords(it) } innerJoin from { SportActivities(it) })
                    .on { record, activity -> record.activity eq activity.id }
                    .select { record, activity ->
                        object {
                            val config = activity.config
                            val record = record.id
                            val userId = record.user
                            val time = record.end
                        }
                    }.where { userId eq user.userId }
                    .group { config }
                    .select {
                        object {
                            val config = key()
                            val count = count { record }
                            val latestTime = max { time }
                        }
                    } innerJoin from { SportConfig(it) })
                    .on { records, config -> records.config eq config.id }
                    .select { records, config ->
                        object {
                            val count = records.count
                            val config = config
                            val time = records.latestTime
                        }
                    }.orderDesc { time }
                    .use {
                        need(it.count)
                        need(it.config.id)
                        need(it.config.name)
                        need(it.config.introduceVideo)
                        need(it.config.trainVideo)
                        need(it.config.mainLogo)
                        need(it.config.description)
                    }
                    .select {
                        object {
                            val id = it.config.id()
                            val name = it.config.name()
                            val introduceVideo = it.config.introduceVideo()
                            val trainVideo = it.config.trainVideo()
                            val mainLogo = it.config.mainLogo()
                            val description = it.config.description()
                            val count = it.count()
                        }
                    }
        }
        apiResult.data = record
        return ResponseEntity.ok(apiResult)
    }

    @GetMapping("/join/{configId}")
    fun joinedSports(@PathVariable("configId") configId: Int): ResponseEntity<Any> {
        val apiResult: ApiResult<*> = ApiResult<Any?>()
        val user = securityChecker.user
        val record = sql.run {
            (from { SportRecords(it) } innerJoin from { SportActivities(it) })
                    .on { record, activity -> record.activity eq activity.id }
                    .select { record, activity ->
                        object {
                            val activity = activity
                            val record = record
                        }
                    }.where { record.user eq user.userId }
                    .where { activity.config eq configId }
                    .select { record }
                    .orderDesc { end }
                    .useAll()
                    .select {
                        object {
                            val id = it.id()
                            val measure = it.measure()
                            val video = it.video()
                        }
                    }
        }
        apiResult.data = record
        return ResponseEntity.ok(apiResult)
    }
}